<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Timer.3 - Binding arguments to a completion handler</title>
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../boost_asio.html" title="Boost.Asio">
<link rel="up" href="../tutorial.html" title="Tutorial">
<link rel="prev" href="tuttimer2/src.html" title="Source listing for Timer.2">
<link rel="next" href="tuttimer3/src.html" title="Source listing for Timer.3">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tuttimer2/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer3/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_asio.tutorial.tuttimer3"></a><a class="link" href="tuttimer3.html" title="Timer.3 - Binding arguments to a completion handler">Timer.3 - Binding arguments
      to a completion handler</a>
</h3></div></div></div>
<p>
        In this tutorial we will modify the program from tutorial Timer.2 so that
        the timer fires once a second. This will show how to pass additional parameters
        to your handler function.
      </p>
<pre class="programlisting"><span class="special">#</span><span class="identifier">include</span> <span class="special">&lt;</span><span class="identifier">functional</span><span class="special">&gt;</span>
<span class="special">#</span><span class="identifier">include</span> <span class="special">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
<span class="special">#</span><span class="identifier">include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">asio</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
        To implement a repeating timer using asio you need to change the timer's
        expiry time in your completion handler, and to then start a new asynchronous
        wait. Obviously this means that the completion handler will need to be able
        to access the timer object. To this end we add two new parameters to the
        <code class="computeroutput"><span class="identifier">print</span></code> function:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            a pointer to a timer object; and
          </li>
<li class="listitem">
            a counter so that we can stop the program when the timer fires for the
            sixth time
          </li>
</ul></div>
<p>
        at the end of the parameter list.
      </p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">print</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">&amp;</span> <span class="comment">/*e*/</span><span class="special">,</span>
    <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">steady_timer</span><span class="special">*</span> <span class="identifier">t</span><span class="special">,</span> <span class="keyword">int</span><span class="special">*</span> <span class="identifier">count</span><span class="special">)</span>
<span class="special">{</span>
</pre>
<p>
        As mentioned above, this tutorial program uses a counter to stop running
        when the timer fires for the sixth time. However you will observe that there
        is no explicit call to ask the io_context to stop. Recall that in tutorial
        Timer.2 we learnt that the boost::asio::io_context::run() function completes
        when there is no more "work" to do. By not starting a new asynchronous
        wait on the timer when <code class="computeroutput"><span class="identifier">count</span></code>
        reaches 5, the io_context will run out of work and stop running.
      </p>
<pre class="programlisting">  <span class="keyword">if</span> <span class="special">(*</span><span class="identifier">count</span> <span class="special">&lt;</span> <span class="number">5</span><span class="special">)</span>
  <span class="special">{</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">count</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
    <span class="special">++(*</span><span class="identifier">count</span><span class="special">);</span>
</pre>
<p>
        Next we move the expiry time for the timer along by one second from the previous
        expiry time. By calculating the new expiry time relative to the old, we can
        ensure that the timer does not drift away from the whole-second mark due
        to any delays in processing the handler.
      </p>
<pre class="programlisting">    <span class="identifier">t</span><span class="special">-&gt;</span><span class="identifier">expires_at</span><span class="special">(</span><span class="identifier">t</span><span class="special">-&gt;</span><span class="identifier">expiry</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">1</span><span class="special">));</span>
</pre>
<p>
        Then we start a new asynchronous wait on the timer. As you can see, the
        <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span></code> function is used to associate the
        extra parameters with your completion handler. The <a class="link" href="../reference/basic_waitable_timer/async_wait.html" title="basic_waitable_timer::async_wait">steady_timer::async_wait()</a>
        function expects a handler function (or function object) with the signature
        <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">&amp;)</span></code>. Binding the additional parameters
        converts your <code class="computeroutput"><span class="identifier">print</span></code> function
        into a function object that matches the signature correctly.
      </p>
<p>
        In this example, the boost::asio::placeholders::error argument to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span></code>
        is a named placeholder for the error object passed to the handler. When initiating
        the asynchronous operation, and if using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span></code>,
        you must specify only the arguments that match the handler's parameter list.
        In tutorial Timer.4 you will see that this placeholder may be elided if the
        parameter is not needed by the completion handler.
      </p>
<pre class="programlisting">    <span class="identifier">t</span><span class="special">-&gt;</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><span class="identifier">print</span><span class="special">,</span>
          <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">placeholders</span><span class="special">::</span><span class="identifier">error</span><span class="special">,</span> <span class="identifier">t</span><span class="special">,</span> <span class="identifier">count</span><span class="special">));</span>
  <span class="special">}</span>
<span class="special">}</span>

<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
  <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_context</span> <span class="identifier">io</span><span class="special">;</span>
</pre>
<p>
        A new <code class="computeroutput"><span class="identifier">count</span></code> variable is added
        so that we can stop the program when the timer fires for the sixth time.
      </p>
<pre class="programlisting">  <span class="keyword">int</span> <span class="identifier">count</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
  <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">steady_timer</span> <span class="identifier">t</span><span class="special">(</span><span class="identifier">io</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">1</span><span class="special">));</span>
</pre>
<p>
        As in Step 4, when making the call to <a class="link" href="../reference/basic_waitable_timer/async_wait.html" title="basic_waitable_timer::async_wait">steady_timer::async_wait()</a>
        from <code class="computeroutput"><span class="identifier">main</span></code> we bind the additional
        parameters needed for the <code class="computeroutput"><span class="identifier">print</span></code>
        function.
      </p>
<pre class="programlisting">  <span class="identifier">t</span><span class="special">.</span><span class="identifier">async_wait</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><span class="identifier">print</span><span class="special">,</span>
        <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">placeholders</span><span class="special">::</span><span class="identifier">error</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">t</span><span class="special">,</span> <span class="special">&amp;</span><span class="identifier">count</span><span class="special">));</span>

  <span class="identifier">io</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
</pre>
<p>
        Finally, just to prove that the <code class="computeroutput"><span class="identifier">count</span></code>
        variable was being used in the <code class="computeroutput"><span class="identifier">print</span></code>
        handler function, we will print out its new value.
      </p>
<pre class="programlisting">  <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"Final count is "</span> <span class="special">&lt;&lt;</span> <span class="identifier">count</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>

  <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
        See the <a class="link" href="tuttimer3/src.html" title="Source listing for Timer.3">full source listing</a>
      </p>
<p>
        Return to the <a class="link" href="../tutorial.html" title="Tutorial">tutorial index</a>
      </p>
<p>
        Previous: <a class="link" href="tuttimer2.html" title="Timer.2 - Using a timer asynchronously">Timer.2 - Using a
        timer asynchronously</a>
      </p>
<p>
        Next: <a class="link" href="tuttimer4.html" title="Timer.4 - Using a member function as a completion handler">Timer.4 - Using a member
        function as a completion handler</a>
      </p>
</div>
<div class="copyright-footer">Copyright © 2003-2025 Christopher M.
      Kohlhoff<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tuttimer2/src.html"><img src="../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../tutorial.html"><img src="../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../boost_asio.html"><img src="../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tuttimer3/src.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
